import React, {
  useEffect,
  useCallback,
  useState,
  useRef,
  useImperativeHandle,
  useMemo,
} from 'react';
import { defaultProps } from '../../schema';
import { Modal, Button, Form, Select, Row, Col, message, Tooltip, Input } from 'antd';
import { FormInstance } from 'antd/lib/form';
import { toJS } from '@formily/reactive';
import { useForm } from '@formily/react';
import { useQueryFields } from '@inbiz/hooks';
import './setting.less';
import EditableTable from '@inbiz/basic/EditableTable';
import { getPlatform, uuid } from '@inbiz/utils';
import { TextWidget, getMessage } from '@inbiz/react';
import { getModelInfo } from '../services';
import { ExclamationCircleOutlined } from '@ant-design/icons';

const { Option, OptGroup } = Select;

const EditableContext = React.createContext<FormInstance<any> | null>(null);

interface FiledItem {
  AnotherName?: string;
  FieldName?: string;
  modelName?: string;
}

interface SaveDataType {
  Value: string;
  Text: string;
  Width: string;
  SelectText: boolean;
  YsField: string;
  modelName: string;
}

type IProps = {
  emit?: (type: any, ...arg: any) => void;
  onChange?: Function;
  value?: object;
} & typeof defaultProps;

const RenderModal = (props: any) => {
  // 分组字段列表
  const [fieldGroupList, $fieldGroupList] = useState<FiledItem[]>([]);
  // 表格数据
  const [dataSource, $dataSource] = useState<any[]>([]);

  // 多模型下字段列表
  const [modelFields, $modelFields] = useState([]);

  // 主模型的modelKey
  const [modelKey, $modelKey] = useState('');
  //所有模型字段
  const [modelFieldsList, $modelFieldsList] = useState([]);

  // 可修改表格form
  const [form] = Form.useForm();
  // formily表单
  const outerForm: any = useForm();

  // 环境
  const ENV = getPlatform();

  const editableRef = useRef<any>();

  const sourceKey = outerForm.fields?.['form.senior.soure.x-component-props.sourceModel']?.value;

  // model字段初始列表
  const [fields] = useQueryFields(
    {
      key: typeof sourceKey === 'string' ? sourceKey : sourceKey?.searchData,
      appId: outerForm.appInfo?.appId,
    },
    [],
  );
  const sourcetype = outerForm.fields?.['form.senior.soure.x-component-props.sourcetype'].value;
  // model列表（拦截无效遍历用）
  const fieldsList = useRef<any[]>([]);

  // 显示配置表格columns
  const columns = useMemo(() => {
    const setWebAttrComponent = () => {
      if (sourcetype == 'api' && sourceKey?.searchData && typeof sourceKey?.searchData == 'object' || sourceKey === undefined) {
        return { type: 'Input' };
      }
      return {
        type: 'Select' as 'Select',
        optgroups: fieldGroupList?.[0]?.modelName
          ? fieldGroupList
          : undefined,
        options: fieldGroupList?.[0]?.modelName ? undefined : fieldGroupList?.[0]?.options || [],
        showSearch: true,
        filterOption: (input, option) => {
          return (option?.value?.toString() ?? '').toLowerCase().includes(input.toLowerCase())
        },
        render: (val: string) => {
          return val?.includes('$') ? val.replace('$', '.') : val;
        },
        afterEdit: (index, record) => {
          if (record.Value?.includes('$')) {
            const [ modelName ] = record.Value.split('$');
            const currentModel = fieldGroupList.find(field => field?.value === modelName);
            const Text = currentModel?.options?.find(ele => ele.value == record.Value)?.columnName;
            return {
              ...record,
              Text
            }
          }
          const Text = fieldGroupList?.find(ele => ele.value == record.Value)?.columnName;
          return {
            ...record,
            Text
          }
        }
      };
    };

    const setWapAttrComponent = () => {
      if (sourcetype == 'api' && sourceKey?.searchData && typeof sourceKey?.searchData == 'object' || sourceKey === undefined) {
        return { type: 'Input' };
      }
      return {
        type: 'Select' as 'Select',
        options: fieldGroupList,
        showSearch: true,
        filterOption: (input: string, option: any) => {
          return (option?.label?.toString() ?? '').toLowerCase().includes(input.toLowerCase())
        },
        render: (val: string) => {
          return val?.includes('$') ? val.replace('$', '.') : val;
        },
        afterEdit: (index, record) => {
          if (record.Value?.includes('$')) {
            const [ modelName ] = record.Value.split('$');
            const currentModel = fieldGroupList.find(field => field?.value === modelName);
            const Text = currentModel?.options?.find(ele => ele.value == record.Value)?.columnName;
            return {
              ...record,
              Text
            }
          }
          const Text = fieldGroupList?.find(ele => ele.value == record.Value)?.columnName;
          return {
            ...record,
            Text
          }
        }
      };
    };

    return ENV === 'web'
      ? [
        {
          title: getMessage('EformDynamicList.fieldName'),
          dataIndex: 'Value',
          width: 200,
          editData: {
            ...setWebAttrComponent(),
            rules: [
              {
                required: true,
              },
            ]
          },
          render: (value: any) => {
            return value?.includes('$') ? value.replace('$', '.') : value;
          },
        },
        {
          title: getMessage('EformDynamicList.columnName'),
          dataIndex: 'Text',
          width: 150,
          editData: {
            type: 'MultilingualInput',
          },
        },
        {
          title: getMessage('EformDynamicList.columnWidth'),
          dataIndex: 'Width',
          width: 100,
          editData: {
            type: 'Input' as 'Input',
          },
        },
        {
          title: getMessage('EformDynamicList.queryField'),
          dataIndex: 'SelectText',
          width: 100,
          editData: {
            type: 'Select' as 'Select',
            options: [
              {
                label: getMessage('EformDynamicList.true'),
                value: true,
                key: '1',
              },
              {
                label: getMessage('EformDynamicList.false'),
                value: false,
                key: '2',
              },
            ],
            rules: [
              {
                required: true,
              },
            ],
          },
        },
      ]
      : [
        {
          title: getMessage('EformDynamicList.fieldName'),
          dataIndex: 'Value',
          // width: 270,
          editData: {
            ...setWapAttrComponent(),
            rules: [
              {
                required: true,
              },
            ],
          },
          render: (value: any) => {
            return value?.includes('$') ? value.replace('$', '.') : value;
          },
        },
        {
          title: getMessage('EformDynamicList.columnName'),
          dataIndex: 'Text',
          // width: 270,
          editData: {
            type: 'MultilingualInput',
          },
        },
      ];
  }, [ENV, fieldGroupList]);

  // 格式化model字段
  useEffect(() => {
    if (Array.isArray(fields) && fields.length && !fieldsList.current.length) {
      let options: any[] = [...fields];
      let number = 0;
      //一对多、多对多数据处理 保存第一次找到主模型的key
      let _options: any[] = [];
      options.map((item) => {
        if (item.childList) {
          item.childList.forEach(child => {
            const childItem = {
              IsMany: item.IsMany,
              Master: item.Master,
              ModelKey: item.ModelKey,
              ModalName: item.value,
              label: child?.label || '',
              showLabel: child.label || '',
              value: child?.value || '',
              ysField: child?.label || '',
              columnName: child?.columnName || '',
              origin_FieldName: child?.value || '',
            };
            _options.push(childItem);
          })
          return item;
        }
        if (number == 0) {
          if (item.Master) {
            $modelKey(item.ModelKey);
            number++;
          }
        }
        _options.push(item);
        return item;
      });
      options = _options;
      options.map((item: any) => {
        let sp = item.origin_FieldName.split('$');
        let sp1 = item.value.split('$');
        item.showLabel = sp1.length > 1 ? sp1[1] : sp1[0];
        item.ysField = sp.length > 1 ? sp[1] : sp[0];
        item.ModelName = sp.length > 1 ? sp[0] : '';
        if (!item.Master && item.label.indexOf('.') === -1 && item.label === item.ysField) {
          item.label = item.ModelName + '.' + item.label;
        }
      });
      fieldsList.current = options;
      $modelFields(options as never[]);
      let list1 = [...options];
      let moList: any[] = [];
      list1.map((item: any) => {
        let type = moList.some((val) => val.modelName === item.ModelName);
        if (type) {
          moList.map((i) => {
            if (i.modelName === item.ModelName) {
              i.options.push(item);
            }
          });
        } else {
          moList.push({
            modelName: item.ModelName,
            label: item.ModelName,
            value: item.ModelName,
            key: item.ModelName,
            options: [item],
          });
        }
      });
      if (!toJS(props.value).options) {
        let arr: any[] = [];
        moList.map((item: any) => {
          item &&
            item.options &&
            item.options.map((val: any) => {
              arr.push({
                Key: uuid(0, 15),
                Value: val.label,
                Text: '',
                Width: 100,
                SelectText: false,
              });
            });
        });
        // $dataSource([...dataSource, ...arr]);
      }

      $fieldGroupList(moList);
      const config: any = toJS(props.value);
      if (!config.selectName || config.selectName === '') {
        form.setFieldsValue({ showName: options[0]?.label });
      }
    }
  }, [fields, dataSource]);

  // 回填数据
  useEffect(() => {
    const config: any = toJS(props.value);
    const arr = [
      { name: 'showName', value: config.selectName },
      { name: 'pageSize', value: config.pageSize || 10 },
      {
        name: 'storageField',
        value: config.storageField || modelFieldsList?.filter((item: any) => item.Primary)[0]?.Name,
      },
      { name: 'showHeader', value: config?.showHeader ?? true },
    ];
    if (Array.isArray(config.list)) {
      const data = config.list.map((item: any) => ({
        Key: uuid(0, 15),
        Value: item.Value,
        Text: item.Text,
        Width: item.Width,
        SelectText: item.SelectText,
      }));
      $dataSource(data);
    }
    form.setFields(arr);
  }, [props.value, modelFieldsList]);

  // 获取模型上所有字段
  useEffect(() => {
    if (modelKey) {
      getModelInfo(outerForm.appInfo?.appId || '', modelKey).then((res) => {
        if (Array.isArray(res) && res.length) {
          let list = res[0].Fields;
          if (Array.isArray(list) && list.length) {
            $modelFieldsList(list);
          }
        }
      });
    }
  }, [modelKey]);

  useImperativeHandle(props.gRef, () => ({
    submit: handleOk,
  }));

  // 确定(提交表单)
  const handleOk = useCallback(async () => {
    let nowData: any[] = await editableRef.current?.getData().catch((error: any) => {
      editableRef.current?.getData();
      throw error;
    });
    let nowFieldList: any[] = [...modelFields];
    if (!nowData.length) {
      message.error(
        `${getMessage('EformDynamicList.tips.fieldList')}${getMessage(
          'EformDynamicList.tips.cannotBeEmpty',
        )}`,
      );
      return;
    }
    let record: any = null;
    let data: SaveDataType[] = [];
    // 去掉key，同时判断数据非空
    for (let i = 0; i < nowData.length; i++) {
      if (!nowData[i].Value || nowData[i].Value === '') {
        record = nowData[i];
        break;
      }
      let field = nowFieldList.filter((item) => item.value === nowData[i].Value);
      let key = field.length ? field[0].ysField : '';
      let model = field.length ? field[0].ModelName : '';
      data.push({
        Value: nowData[i].Value,
        Text: nowData[i].Text,
        Width: nowData[i].Width,
        SelectText: nowData[i].SelectText,
        YsField: key,
        modelName: model,
      });
    }
    if (!record) {
      let arr: string[] = [];
      let cf: boolean = false;
      // 循环遍历判断是否有重复value值
      for (let i = 0; i < nowData.length; i++) {
        if (arr.indexOf(nowData[i].Value) >= 0) {
          message.error(getMessage('EformDynamicList.tips.duplicateRecordsCannotBeAdded'));
          cf = true;
          break;
        }
        arr.push(nowData[i].Value);
      }
      if (!cf) {
        form.validateFields().then((res) => {
          let model = '';
          for (let i = 0; i < nowFieldList.length; i++) {
            if (nowFieldList[i].label === res.showName) {
              model = nowFieldList[i].ModelName || '';
            }
          }
          // 检查是否配置查询字段及添加默认
          const have = data.some((item) => item.SelectText);
          if (!have) {
            let select = res.showName;
            data.map((item) => {
              if (item.Value === select) {
                item.SelectText = true;
              }
            });
          }
          let config = {
            selectName: res.showName,
            pageSize: res.pageSize,
            storageField: res.storageField,
            list: data,
            modelName: model,
            showHeader: res.showHeader,
          };
          props.onChange && props.onChange(config);
          props.hide && props.hide();
        });
      }
    } else {
      let type = !record.Value || record.Value === '' ? 'Value' : 'Text';
      document.getElementById(`cell-${type}-${record.Key}`)?.click();
      setTimeout(() => {
        form.validateFields([type]);
      });
    }
  }, [dataSource, modelFields]);

  // 添加
  const dataAdd = useCallback(() => {
    return { Key: uuid(0, 15), Width: 100, SelectText: false };
  }, []);

  return (
    <div className="eform-dynamic-list-setting-modal">
      <Form form={form} component={false} labelCol={{ span: 7 }}>
        <EditableContext.Provider value={form}>
          <Row>
            <Col span={12}>
              <Form.Item
                name="showName"
                label={getMessage('EformDynamicList.displayFields')}
                rules={[
                  {
                    required: true,
                    message: `${getMessage('EformDynamicList.displayFields')}${getMessage(
                      'EformDynamicList.tips.cannotBeEmpty',
                    )}`,
                  },
                ]}
              >
                {
                  (sourceKey?.searchData && typeof sourceKey?.searchData == 'object' || sourceKey === undefined) ? (
                    <Input />
                  ) : (
                    <Select
                      showSearch
                      filterOption={(input, option) =>
                        (option?.value?.toString() ?? '').toLowerCase().includes(input.toLowerCase())
                      }
                      placeholder={getMessage('EformDynamicList.pleaseSelect')}>
                      {fieldGroupList.map((item: any) =>
                        !item.modelName || item.modelName == '' ? (
                          item?.options.map((val: any) => (
                            <Option value={val.label} key={val.label}>
                              {val.showLabel}
                            </Option>
                          ))
                        ) : (
                          <OptGroup label={item.modelName}>
                            {item?.options.map((val: any) => (
                              <Option value={val.label} key={val.label}>
                                {val.showLabel}
                              </Option>
                            ))}
                          </OptGroup>
                        ),
                      )}
                    </Select>
                  )
                }
              </Form.Item>
            </Col>
            <Col span={10} offset={1}>
              <Form.Item
                name="pageSize"
                label={getMessage('EformDynamicList.pageSize')}
                initialValue={10}
              >
                <Select>
                  <Option value={5}>5</Option>
                  <Option value={10}>10</Option>
                  <Option value={20}>20</Option>
                  <Option value={30}>30</Option>
                  <Option value={40}>40</Option>
                  <Option value={50}>50</Option>
                </Select>
              </Form.Item>
            </Col>
          </Row>
          <Row>
            {(sourcetype == 'model' && sourceKey !== undefined) && (
              <Col span={12}>
                <Form.Item
                  name="storageField"
                  label={
                    <span>
                      <span style={{ paddingRight: '5px' }}>
                        {getMessage('EformDynamicList.storageField')}
                      </span>
                      <Tooltip title={getMessage('EformDynamicList.messageTooltip')}>
                        <ExclamationCircleOutlined />
                      </Tooltip>
                    </span>
                  }
                  initialValue={modelFieldsList?.filter((item: any) => item.Primary)[0]?.Name}
                >
                  <Select
                    showSearch
                    filterOption={(input, option) =>
                      (option?.value?.toString() ?? '').toLowerCase().includes(input.toLowerCase())
                    }
                    placeholder={getMessage('EformDynamicList.pleaseSelect')}>
                    {modelFieldsList?.map((item: any) => (
                      <Option value={item.Name} key={item.Name}>
                        {item.Name}
                      </Option>
                    ))}
                  </Select>
                </Form.Item>
              </Col>
            )}
            {getPlatform() == 'web' && (
              <Col span={sourcetype == 'model' && sourceKey !== undefined ? 10 : 12} offset={sourcetype == 'model' && sourceKey !== undefined ? 1 : 0}>
                <Form.Item name="showHeader" label={'表头'} initialValue={true}>
                  <Select>
                    <Option value={true}>显示</Option>
                    <Option value={false}>隐藏</Option>
                  </Select>
                </Form.Item>
              </Col>
            )}
          </Row>
        </EditableContext.Provider>
      </Form>
      <EditableTable
        rowKey={'Key'}
        columns={columns}
        dataSource={dataSource}
        deleteBtn={{ children: getMessage('EformDynamicList.delete'), danger: true }}
        scroll={{ y: 260 }}
        addBtn={{ children: getMessage('EformDynamicList.add'), type: 'primary' }}
        onAdd={dataAdd}
        ref={editableRef}
      // disableDraggable={true}
      />
    </div>
  );
};

const SettingView = (props: IProps) => {
  // Modal的显示控制状态
  const [isModalVisible, $isModalVisible] = useState(false);
  // formily表单
  const outerForm: any = useForm();

  const child = useRef();

  // 显示配置数据源Modal
  const showModal = () => {
    // const key: string =
    //   outerForm.fields?.['form.senior.soure.x-component-props.sourceModel']?.value;
    // if (key && key !== '') {
    //   $isModalVisible(true);
    // } else {
    //   message.warning(getMessage('EformDynamicList.tips.pleaseSelectTheQueryDataSourceFirst'));
    // }
    $isModalVisible(true)
  };

  // 不保存关闭Modal框（取消）
  const handleCancel = () => {
    $isModalVisible(false);
  };

  const handleOk = () => {
    let any: any = child.current;
    any && any.submit && any.submit();
  };

  return (
    <div className="dynamic-setting-nav">
      <Button type="primary" onClick={showModal}>
        <TextWidget>EformDynamicList.configure</TextWidget>
      </Button>
      <Modal
        title={getMessage('EformDynamicList.configure')}
        visible={isModalVisible}
        onOk={handleOk}
        onCancel={handleCancel}
        okText={getMessage('global.sure')}
        cancelText={getMessage('EformDynamicList.cancel')}
        destroyOnClose
        width={700}
        // getContainer={false}
        isMove
      >
        <RenderModal gRef={child} hide={handleCancel} {...props} />
      </Modal>
    </div>
  );
};

export default SettingView;
